﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace BeiXun.Shared.WebControls
{
    /// <summary>
    /// 选择日期时间
    /// </summary>
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:DatePicker runat=\"server\"></{0}:DatePicker>")]
    public class DatePicker : TextBox
    {
        /// <summary>
        /// 默认日期时间格式，必须与 WdatePicker.js 定义的格式一致。

        /// </summary>
        private const string DEFAULT_FORMAT = "yyyy-MM-dd";
        /// <summary>
        /// 本控件的资源文件的路径

        /// </summary>
        private const string RESOURCE_PATH = "~/Scripts/DatePicker/";
        /// <summary>
        /// 本控件的资源文件的绝对路径

        /// </summary>
        private static string resourcePath = null;
        /// <summary>
        /// 本控件的日期时间格式
        /// </summary>
        private string _datetimeFormat = DEFAULT_FORMAT;
        /// <summary>
        /// 是否显示日期时间控件的触发按钮（图片）

        /// </summary>
        private bool _showTrigger = false;
        /// <summary>
        /// 控件的内容是否只读

        /// </summary>
        private bool _readOnly = false;
        /// <summary>
        /// 日期时间控件的参数集合

        /// </summary>
        private DatePickerParameterCollection _parameters = null;
        private string _maximum = null;
        private string _minimum = null;
        private bool _isShowWeek = false;

        protected override void Render(HtmlTextWriter writer)
        {
            if (!String.IsNullOrEmpty(this.DateTimeFormat))
            {
                this.Parameters.Add("dateFmt", this.DateTimeFormat, true);
            }

            if (this.ReadOnly)
            {
                this.Parameters.Add("isShowClear", "false", false);
                this.Parameters.Add("readOnly", "true", false);
            }

            if (!String.IsNullOrEmpty(this.Maximum))
            {
                this.Parameters.Add("maxDate", this.Maximum, true);
            }
            if (!String.IsNullOrEmpty(this.Minimum))
            {
                this.Parameters.Add("minDate", this.Minimum, true);
            }
            if (this.ShowWeek)
            {
                this.Parameters.Add("isShowWeek", "true", false);
            }

            // 设置控件的 onclick 客户端事件

            string strOldEvent = base.Attributes["onclick"];
            string strNewEventParam = this.GetParameters();
            string strNewEvent = String.Format("WdatePicker({0});", String.IsNullOrEmpty(strNewEventParam) ? "" : ("{" + strNewEventParam + "}"));

            if (strOldEvent == null || strOldEvent.Trim().Length == 0)
            {
                base.Attributes.Add("onclick", strNewEvent);
            }
            else
            {
                base.Attributes["onclick"] = strNewEvent + strOldEvent;
            }

            base.Render(writer);

            // 如果显示日期时间的触发按钮，则在控件后面添加一个图片

            if (this.ShowTrigger)
            {
                this.Parameters.Add("el", String.Format("$dp.$('{0}')", base.ClientID), false);

                writer.Write("<img onclick=\"WdatePicker({0});\" src=\"{1}skin/datePicker.gif\" style=\"width:16px;height:22px;vertical-align:middle;cursor:pointer;border:0px;\" class=\"datetime_trigger\" alt=\"点击设置日期\" />",
                    "{" + this.GetParameters() + "}",
                    this.ResourcePath);
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.RegisterClientScriptResource();
        }

        private string ResourcePath
        {
            get
            {
                if (resourcePath == null)
                {
                    // 获取控件的资源文件的绝对路径
                    string strResPath = RESOURCE_PATH ?? String.Empty;
                    if (strResPath.Length != 0)
                    {
                        strResPath = strResPath.Replace('\\', '/');
                        if (strResPath.StartsWith("~"))
                        {
                            strResPath = VirtualPathUtility.ToAbsolute(strResPath);
                        }
                        strResPath = VirtualPathUtility.AppendTrailingSlash(strResPath);
                    }
                    resourcePath = strResPath;
                }

                return resourcePath;
            }
        }

        /// <summary>
        /// 获取或者设置日期时间的格式
        /// </summary>
        [DefaultValue(DEFAULT_FORMAT)]
        public string DateTimeFormat
        {
            get
            {
                return this._datetimeFormat;
            }
            set
            {
                string s = value;
                if (s != null) s = s.Trim();
                this._datetimeFormat = s;
            }
        }

        /// <summary>
        /// 获取或者设置日期时间的触发按钮是否显示
        /// </summary>
        [DefaultValue(false)]
        public bool ShowTrigger
        {
            get { return this._showTrigger; }
            set { this._showTrigger = value; }
        }

        /// <summary>
        /// 获取或者设置控件的值，此值必须为 DateTime 类型
        /// </summary>
        [DefaultValue((string)null)]
        public object Value
        {
            get
            {
                string strDate = base.Text.Trim();
                if (strDate.Length != 0)
                {
                    DateTime dt;
                    if (DateTime.TryParse(strDate, out dt)) return dt;
                }
                return null;
            }
            set
            {
                if (value != null && value.GetType().Equals(typeof(DateTime)))
                {
                    DateTime dt = (DateTime)value;
                    if (String.IsNullOrEmpty(this.DateTimeFormat))
                        base.Text = dt.ToString();
                    else
                        base.Text = dt.ToString(this.DateTimeFormat);
                }
            }
        }

        /// <summary>
        /// 获取或者设置控件的文本，此值是有效的日期时间字符串
        /// </summary>
        public override string Text
        {
            get
            {
                string strDate = base.Text.Trim();
                if (strDate.Length != 0)
                {
                    DateTime dt;
                    if (DateTime.TryParse(strDate, out dt))
                    {
                        if (String.IsNullOrEmpty(this.DateTimeFormat))
                            return dt.ToString();
                        else
                            return dt.ToString(this.DateTimeFormat);
                    }
                }
                return String.Empty;
            }
            set
            {
                base.Text = String.Empty;
                if (value != null)
                {
                    string strDate = value.Trim();
                    if (strDate.Length != 0)
                    {
                        DateTime dt;
                        if (DateTime.TryParse(strDate, out dt))
                        {
                            if (String.IsNullOrEmpty(this.DateTimeFormat))
                                base.Text = dt.ToString();
                            else
                                base.Text = dt.ToString(this.DateTimeFormat);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 获取或设置一个值，用于指示能否更改 TextBox 控件的内容。

        /// </summary>
        public override bool ReadOnly
        {
            get { return this._readOnly; }
            set { this._readOnly = value; }
        }

        /// <summary>
        /// 获取日期时间控件的参数，详见 http://www.my97.net/dp/demo/index.htm
        /// </summary>
        [Browsable(false), DefaultValue((string)null), PersistenceMode(PersistenceMode.InnerProperty)]
        public DatePickerParameterCollection Parameters
        {
            get
            {
                if (this._parameters == null)
                {
                    this._parameters = new DatePickerParameterCollection();
                }
                return this._parameters;
            }
        }

        /// <summary>
        /// 获取或设置日期时间显示框（也称作 DatePicker 控件）的最大值

        /// </summary>
        [DefaultValue((string)null)]
        public string Maximum
        {
            get
            {
                return this._maximum;
            }
            set
            {
                string s = value;
                if (s != null) s = s.Trim();
                this._maximum = s;
            }
        }

        /// <summary>
        /// 获取或设置日期时间显示框（也称作 DatePicker 控件）的最小允许值

        /// </summary>
        [DefaultValue((string)null)]
        public string Minimum
        {
            get
            {
                return this._minimum;
            }
            set
            {
                string s = value;
                if (s != null) s = s.Trim();
                this._minimum = s;
            }
        }

        /// <summary>
        /// 获取或设置日期选择窗口是否显示星期
        /// </summary>
        [DefaultValue(false)]
        public bool ShowWeek
        {
            get { return _isShowWeek; }
            set { _isShowWeek = value; }
        }

        /// <summary>
        /// 注册控件的 JavaScript 资源
        /// </summary>
        private void RegisterClientScriptResource()
        {
            string strJsPath = this.ResourcePath + "WdatePicker.js";
            ClientScriptManager clientScript = this.Page.ClientScript;

            if (!clientScript.IsClientScriptIncludeRegistered(this.GetType(), strJsPath))
            {
                clientScript.RegisterClientScriptInclude(this.GetType(), strJsPath, strJsPath);
            }
        }

        private string GetParameters()
        {
            if (this._parameters == null) return null;
            return this._parameters.ToString();
        }
    }

    /// <summary>
    /// 日期时间控件的参数集合类
    /// </summary>
    public class DatePickerParameterCollection : List<DatePickerParameter>
    {
        /// <summary>
        /// 添加参数
        /// </summary>
        /// <param name="name">参数名称</param>
        /// <param name="value">参数的值</param>
        /// <param name="isString">参数的值是否为字符串</param>
        public void Add(string name, string value, bool isString)
        {
            this.Add(new DatePickerParameter(name, value, isString));
        }

        /// <summary>
        /// 获取日期时间控件参数集合的字符串
        /// </summary>
        /// <returns>字符串形式的参数</returns>
        public override string ToString()
        {
            Dictionary<string, DatePickerParameter> paramTable = new Dictionary<string, DatePickerParameter>();

            for (int i = 0; i < this.Count; i++)
            {
                DatePickerParameter param = this[i];
                paramTable[param.Name] = param;
            }

            if (paramTable.Count > 0)
            {
                StringBuilder paramBuilder = new StringBuilder();

                foreach (KeyValuePair<string, DatePickerParameter> entry in paramTable)
                {
                    if (paramBuilder.Length > 0)
                        paramBuilder.Append("," + entry.Value.ToString());
                    else
                        paramBuilder.Append(entry.Value.ToString());
                }

                return paramBuilder.ToString();
            }

            return null;
        }
    }

    /// <summary>
    /// 日期时间控件的参数

    /// </summary>
    public class DatePickerParameter
    {
        private string _name = null;
        private string _value = null;
        private bool _isString = true;

        public DatePickerParameter()
        {
        }

        public DatePickerParameter(string name, string value, bool isString)
        {
            this.IsString = isString;
            this.Name = name;
            this.Value = value;
        }

        /// <summary>
        /// 获取或者设置参数的名称
        /// </summary>
        public string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                if (value == null || value.Trim().Length == 0)
                {
                    throw new Exception("参数名称不能为空（null或String.Empty）。");
                }
                this._name = value.Trim();
            }
        }

        /// <summary>
        /// 获取或者设置参数的值

        /// </summary>
        [DefaultValue("")]
        public string Value
        {
            get
            {
                return this._value;
            }
            set
            {
                if (value == null)
                {
                    this._value = "null";
                    this.IsString = false;
                }
                else
                {
                    this._value = value;
                }
            }
        }

        /// <summary>
        /// 获取或设置一个值，用于指示参数值是否为字符串类型，默认为 true
        /// </summary>
        [DefaultValue(true)]
        public bool IsString
        {
            get { return this._isString; }
            set { this._isString = value; }
        }

        /// <summary>
        /// 比较两个参数是否相等，仅比较参数的名称

        /// </summary>
        /// <param name="parameter">要比较的另一参数对象</param>
        /// <returns></returns>
        public bool Equals(DatePickerParameter parameter)
        {
            return this.Name == parameter.Name;
        }

        /// <summary>
        /// 获取参数的字符串形式，如：name:value
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return String.Format("{0}:{2}{1}{2}",
                this.Name,
                this.IsString ? this.Value.Replace("'", "\\'") : this.Value,
                this.IsString ? "'" : "");
        }
    }
}
